package com.joven.shelltest.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author wzj
 * @Date 2023-11-20 14:51
 **/
public class IdCardUtils {

    public static final int ID_CARD_LEN = 18;
    public static final String MAN = "男";
    public static final String WOMEN = "女";
    public static final String FORMATTER_UN_STRIP = "yyyyMMdd";

    /**
     * 身份证号校验
     * @param idCard
     * @return
     */
    public static boolean verifyIdCard(String idCard) {
        String checkCode = getCheckCode(idCard);

        String pattern = "^\\d{17}[0-9Xx]$";
        Pattern regex = Pattern.compile(pattern);
        Matcher matcher = regex.matcher(idCard);

        if (idCard.length() != ID_CARD_LEN) {
            System.out.println("身份证号码长度不正确");
            return false;
        } else if (!matcher.matches()) {
            System.out.println("身份证号码前17位不是数字");
            return false;
        } else if (!String.valueOf(idCard.charAt(17)).equals(checkCode)) {
            System.out.println("身份证号码校验失败");
            return false;
        } else {
            return true;
        }
    }

    private static String getCheckCode(String idCard) {
        int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        int sum = 0;
        for (int i = 0; i < 17; i++) {
            char c = idCard.charAt(i);
            int digit = Character.getNumericValue(c);
            sum += digit * weights[i];
        }
        int mod = sum % 11;
        String[] checkCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
        return checkCodes[mod];
    }

    public static String getBirthDate(String idCardNo) {
        if (idCardNo == null || idCardNo.length() != ID_CARD_LEN) {
            return null;
        }
        String birthYear = idCardNo.substring(6, 10);
        String birthMonth = idCardNo.substring(10, 12);
        String birthDay = idCardNo.substring(12, 14);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, Integer.parseInt(birthYear));
        cal.set(Calendar.MONTH, Integer.parseInt(birthMonth) - 1);
        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(birthDay));
        return cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH);
    }

    public static boolean isNearTermRetirementUser(String idCard) {
        // 获取身份证中的性别
        String gender = getGenderFromIdCard(idCard);

        // 判断男性退休年龄为60，女性退休年龄为55
        int retirementAge = gender.equals(MAN) ? 60 : 55;

        // 判断客户年龄是否近三年退休
        return isRetirementAgeNear(idCard, retirementAge);
    }

    public static boolean isRetirementAgeNear(String idCard, int retirementAge) {

        // 获取身份证中的出生日期
        LocalDate birthDate = getBirthDateFromIdCard(idCard);

        // 计算当前日期与出生日期之间的年龄差
        long age = ChronoUnit.YEARS.between(birthDate, LocalDate.now());

        // 判断年龄是否在退休前三年内
        return age >= retirementAge - 3;
    }

    public static String getGenderFromIdCard(String idCard) {
        // 根据身份证中的规则提取性别，这里以省略具体实现为例
        // 假设身份证中的性别信息为第17位字符，偶数为女性，奇数为男性
        int genderCode = Integer.parseInt(Character.toString(idCard.charAt(16)));

        // 根据性别码返回性别字符串
        return genderCode % 2 == 0 ? WOMEN : MAN;
    }

    public static LocalDate getBirthDateFromIdCard(String idCard) {
        // 根据身份证中的规则提取出生日期，这里以省略具体实现为例
        // 假设身份证中的出生日期格式为yyyy-MM-dd
        String birthDateStr = idCard.substring(6, 14);
        // 定义日期格式化模式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(FORMATTER_UN_STRIP);

        // 将字符串类型的日期解析为LocalDate对象
        return LocalDate.parse(birthDateStr, formatter);
    }

    public static String getBirthDateStr(String idCard) {
        return idCard.substring(6, 14);
    }

    public static String formatBirthDay(String inputDate) {
        if (StringUtils.isNotEmpty(inputDate)) {
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyyMMdd");
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy年MM月dd日");
            try {
                Date date = inputFormat.parse(inputDate);
                return outputFormat.format(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

}
